/**
 * 
 */
package com.ezops.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.parser.ImageRenderInfo;
import com.itextpdf.text.pdf.parser.PdfImageObject;
import com.itextpdf.text.pdf.parser.PdfReaderContentParser;
import com.itextpdf.text.pdf.parser.RenderListener;
import com.itextpdf.text.pdf.parser.TextRenderInfo;

/**
 * @author Administrator
 * 
 */
public class PDFReader {

	final static Logger logger = LoggerFactory.getLogger(PDFReader.class);
	public static final String TYPE_PNG = "png";
	public static final String TYPE_JPG = "jpg";
	public static final String TYPE_TIF = "tif";

	
	/**
	 * Parses a PDF and extracts all the images present in PDF file.
	 * @param source the source PDF
	 * @param destination the directory to save images
	 */
	public List<byte[]> extractImages(String source, String fieName,String destination){
		List<byte[]> raw = null;
		try{
			//Check for destination folder
			File fileDir = new File(destination);
			if (!fileDir.exists()) {
				if (fileDir.mkdir()) {//To Avoid FNF Exception 
				}
			}
			String imageName = FilenameUtils.removeExtension(fieName);
			PdfReader reader = new PdfReader(source);
			PdfReaderContentParser parser = new PdfReaderContentParser(reader);
			String path = destination+ "/" + imageName + "%s.%s";
			ImageRenderListener listener = new ImageRenderListener(path);
			for (int i = 1; i <= reader.getNumberOfPages(); i++) {
				parser.processContent(i, listener);
			}
			reader.close();
			raw =listener.getRawData();

		}catch(Exception ex){
			ex.printStackTrace();
		}
		return raw;
	}

	/**
	 * Read Byte[] from input file
	 * 
	 * @param sourceDir
	 * @return dataList
	 */
	public List<byte[]> readFiles(String sourceDir) {
		List<byte[]> dataList = new ArrayList<byte[]>();
		File folder = new File(sourceDir);
		if (folder.isDirectory()) {
			byte[] dataByte = null;
			File[] listOfFiles = folder.listFiles();
			for (int i = 0; i < listOfFiles.length; i++) {
				if (listOfFiles[i].isFile()) {
					String files = listOfFiles[i].getName();
					if (files.endsWith(PDFReader.TYPE_JPG)) {
						InputStream is;
						try {
							is = new FileInputStream(listOfFiles[i]);
							dataByte = IOUtils.toByteArray(is);
							dataList.add(dataByte);
						} catch (FileNotFoundException e) {
							e.printStackTrace();
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}
			}
		}
		return dataList;
	}

	public void writeFile(byte[] bytes, String path) {
		FileOutputStream fos;
		try {
			fos = new FileOutputStream(new File(path));
			fos.write(bytes);
			fos.flush();
			fos.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	class ImageRenderListener implements RenderListener {
		protected String path;
		protected String imageType;

		private List<byte[]> rawData = new ArrayList<byte[]>();

		public List<byte[]> getRawData() {
			return rawData;
		}

		public void setRawData(List<byte[]> rawData) {
			this.rawData = rawData;
		}

		public void put(byte[] rawImage) {
			rawData.add(rawImage);
		}

		public String getImageType() {
			return imageType;
		}

		public void setImageType(String imageType) {
			this.imageType = imageType;
		}

		/**
		 * Creates a RenderListener that will look for images.
		 */
		public ImageRenderListener(String path) {
			this.path = path;
		}

		public ImageRenderListener(String path, String imageType) {
			this.path = path;
			this.imageType = imageType;
		}

		/**
		 * Render input Image
		 */
		@Override
		public void renderImage(ImageRenderInfo arg0) {
			try {
				//1- Get image 
				PdfImageObject image = arg0.getImage();
				if (image == null) {
					//System.out.println("Input file" + path + " contain no image...");
					return;
				}
				//2- Create output file name
				String filename = String.format(path,arg0.getRef().getNumber(), image.getFileType());
				//System.out.println("Extracted image file name ==>"+ filename);
				//3- Write file to physical location with same name as input file name 
				 //writeFile(image, filename);
				//4- Store byte array for later use
				put(image.getImageAsBytes());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		/**
		 * write File
		 * 
		 * @param image
		 * @param filename
		 */
		private void writeFile(PdfImageObject image, String filename) {
			FileOutputStream os;
			try {
				//System.out.println("Extracted Image Fies--->" + filename);
				os = new FileOutputStream(filename);
				os.write(image.getImageAsBytes());
				os.flush();
				os.close();
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		@Override
		public void beginTextBlock() {
			// TODO Auto-generated method stub

		}

		@Override
		public void endTextBlock() {
			// TODO Auto-generated method stub

		}

		@Override
		public void renderText(TextRenderInfo arg0) {
			// TODO Auto-generated method stub

		}
	}
}
